﻿using G19Glower.Shared;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace G19Glower.App
{
    internal class SettingsManager : ISettingsManager
    {
        private const string SETTINGS_LOCATION = "GlowerSettings.xml";

        private XElement mSettingsRootElement;
        private XElement mRunningGlowiesElement;
        private Dictionary<ISettings, XElement> mSettings = new Dictionary<ISettings, XElement>();
        private bool mIsSaved = false;

        #region .ctor

        internal SettingsManager()
        {
            try
            {
                if (System.IO.File.Exists(SETTINGS_LOCATION))
                {
                    mSettingsRootElement = XElement.Load(SETTINGS_LOCATION);
                    mRunningGlowiesElement = mSettingsRootElement.Element("RunningGlowies");
                    mIsSaved = true;
                }
            }
            catch
            {
                // meh
            }

            if (mSettingsRootElement == null)
            {
                mSettingsRootElement = new XElement("GlowerSettings");
            }
            if (mRunningGlowiesElement == null)
            {
                mRunningGlowiesElement = new XElement("RunningGlowies");
                mSettingsRootElement.Add(mRunningGlowiesElement);
            }
        }

        #endregion

        #region Properties

        internal bool IsSaved { get { return mIsSaved; } }

        #endregion

        #region Internal Methods

        internal IEnumerable<ISettings> GetSettings()
        {
            return mSettings.Keys;
        }

        internal void Save()
        {
            try
            {
                mSettingsRootElement.Save(SETTINGS_LOCATION);
                mIsSaved = true;
            }
            catch
            {

            }
        }

        internal IEnumerable<string> GetRunningGlowies()
        {
            return mRunningGlowiesElement.Elements("Glower").Select((glowerElement) => glowerElement.Value);
        }

        internal void SetRunningGlowies(IEnumerable<string> glowies)
        {
            mRunningGlowiesElement.RemoveNodes();
            foreach (string glowerName in glowies)
            {
                mRunningGlowiesElement.Add(new XElement("Glower", glowerName));
            }
        }

        #endregion

        #region ISettingsManager Members

        void ISettingsManager.RegisterSettings(ISettings settings)
        {
            string settingsName = settings.GetType().FullName;

            // Try find existing settings store
            XElement settingsStore = mSettingsRootElement.Elements("Settings").FirstOrDefault((element) => {
                var nameAttr = element.Attribute("Name");
                return nameAttr != null && string.Equals(nameAttr.Value, settingsName);
            });

            if (settingsStore == null)
            {
                // Create new settings store
                settingsStore = new XElement("Settings", 
                                             new XAttribute("Name", settingsName),
                                             new XElement("Store"));

                mSettingsRootElement.Add(settingsStore);
            }

            // TODO: should probably detach the store element from tree
            settingsStore = settingsStore.Element("Store");
            mSettings.Add(settings, settingsStore);

            settings.Initialize(settingsStore);
        }

        #endregion
    }
}
